class Player extends AcGameObject{
    constructor (playground, x , y , radius , color , speed , character, username , photo) {
        super();
        this.playground = playground;
        this.ctx = this.playground.game_map.ctx;
        this.x = x;
        this.y = y;
        this.vx = 0;
        this.vy = 0;
        this.damagex = 0; // 被击中后移动控制方向
        this.damagey = 0 ;
        this.damage_speed = 0;
        this.friction = 0.9; // 击中后速度越来越慢 即摩擦力
        this.move_length=0; // 移动距离
        this.color = color;
        this.speed = speed;   // 速度，根据百分比
        this.radius = radius; // 半径
        this.character = character;  // 是否是玩家自己，使用鼠标键盘操作
        this.eps = 0.01;  // 误差是0.1级别的，小于0.1算0 ，即增加期望值
        this.cur_skill = null ; // 选择的技能是什么
        this.username = username;
        this.photo = photo;
        this.spent_time = 0 ;
        this.state = "com"; // com 正常 ， vertigo 眩晕
        this.vertigo_time = 0;
        this.fireballs = [];
        if(this.character !==  "robot"){ //再构造函数中加上图像数据
            this.img=new Image();
            this.img.src=photo;
        }
        if(this.character === "me"){
            this.fireball_coldtime = 3;   // 火球技能CD3秒
            this.fireball_img = new Image();
            this.fireball_img.src = "https://cdn.acwing.com/media/article/image/2021/12/02/1_9340c86053-fireball.png";

            this.blink_coldtime = 5;
            this.blink_img = new Image();
            this.blink_img.src = "https://cdn.acwing.com/media/article/image/2021/12/02/1_daccabdc53-blink.png";

            this.vertigo_coldtime = 5 ;
            this.vertigo_img = new Image();
            this.vertigo_img.src = "https://cloud-minapp-39228.cloud.ifanrusercontent.com/1nM87YrDLBD4DTQD.png"
        }
    }

    start(){
        this.playground.player_count++;
        this.playground.noticeborad.write("已就绪: " + this.playground.player_count +"人");

        if(this.playground.player_count >= 2){
            this.playground.state = "fighting";
            this.playground.noticeborad.write("游戏开始!!");
        }
        if(this.character === "me"){
            this.add_listening_events();
        }else if(this.character === "robot"){
            let tx = Math.random() * this.playground.width / this.playground.scale;
            let ty = Math.random() * this.playground.height / this.playground.scale;;
            this.move_to(tx,ty);
        }
    }

    add_listening_events(){
        var that = this
        this.playground.game_map.$canvas.on("contextmenu",function(){
            return false;
        });
        this.playground.game_map.$canvas.mousedown(function(e){

            if(that.playground.state !== "fighting")
                return true;

            const rect = that.ctx.canvas.getBoundingClientRect();
            if ( e.which === 3)  { // 右键3 左键1 滚轮2
                if(that.state !== "vertigo"){
                    let tx = (e.clientX-rect.left)/that.playground.scale;
                    let ty = (e.clientY-rect.top)/that.playground.scale;
                    that.move_to( (e.clientX-rect.left) / that.playground.scale, (e.clientY - rect.top) / that.playground.scale);

                    if(that.playground.mode === "multi mode"){
                        that.playground.mps.send_move_to(tx,ty)
                    }
                }
            } else if(e.which === 1 && that.state === "com") {
                let tx = (e.clientX-rect.left)/that.playground.scale;
                let ty = (e.clientY-rect.top)/that.playground.scale;
                if(that.cur_skill === "fireball"){
                    if(that.fireball_coldtime > that.eps)
                        return false;
                    that.fireball_voice()
                    var fireball = that.shoot_fireball((e.clientX - rect.left)/ that.playground.scale, (e.clientY - rect.top)/ that.playground.scale);
                    if(that.playground.mode === "multi mode"){
                        that.playground.mps.send_shoot_fireball(tx,ty,fireball.uuid);
                    }
                }else if (that.cur_skill === "blink"){
                    if(that.blink_coldtime > that.eps)
                        return false;
                    that.blink_voice()
                    that.blink(tx,ty);
                    if(that.playground.mode === "multi mode"){
                        that.playground.mps.send_blink(tx,ty);
                    }
                }else if(that.cur_skill === "vertigo"){
                    if(that.vertigo_coldtime > that.eps)
                        return false;
                    that.vertigoball_voice()
                    var vertigo = that.shoot_vertigo(tx,ty);
                    if(that.playground.mode === "multi mode"){
                        that.playground.mps.send_shoot_vertigo(tx,ty,vertigo.uuid);
                    }
                }
                that.cur_skill = null;
            }
        });
        this.playground.game_map.$canvas.keydown(function(e){

            if(e.which === 13) { // enter
                if(that.playground.mode === "multi mode"){
                    that.playground.chat_field.show_input();  // 打开聊天框
                }
            }else if (e.which === 27){
                if(that.playground.mode === "multi mode"){  // 关闭聊天框
                    that.playground.chat_field.hide_input()
                }
            }

            if(that.playground.state !== "fighting")
                return true;
            if(that.state === "vertigo"){
                that.vertigo_voice()
                return true;
            }
            if(e.which === 81){      // 使用keycode ， 表示q
                if(that.fireball_coldtime > that.eps)
                    return true;
                that.cur_skill = "fireball";
                return false;
            }else if (e.which === 70){
                if(that.blink_coldtime > that.eps)
                    return true;
                that.cur_skill = "blink";
                return false;
            }else if (e.which === 69){  // E
                console.log(that.vertigo_coldtime)
                if(that.vertigo_coldtime > that.eps)
                    return true;
                that.cur_skill = "vertigo";
            }
        });
    }   
    fireball_voice() {
                var audio = document.createElement("audio");
                audio.src = 'https://cloud-minapp-39228.cloud.ifanrusercontent.com/1nNFAy0zO879Kfvm.mp3';
                audio.play();
    }

    blink_voice(){
        var audio = document.createElement("audio");
        audio.src='https://cloud-minapp-39228.cloud.ifanrusercontent.com/1nNFGL4UxFPsXC4N.mp3';
        audio.play();
    }
    
    vertigoball_voice(){
        var audio = document.createElement("audio");
        audio.src = 'https://cloud-minapp-39228.cloud.ifanrusercontent.com/1nNFByPZDzbWhCyp.mp3';
        audio.play();
    }
    get_dist(x1,y1,x2,y2){ //计算距离
        let dx = x1 - x2;
        let dy = y1 - y2;
        return Math.sqrt(dx * dx + dy * dy);
    }

    move_to(tx, ty){ // 判断移动方向
        this.move_length = this.get_dist(this.x,this.y,tx,ty);
        let angle = Math.atan2(ty-this.y,tx-this.x);  // 求位移角度
        this.vx = Math.cos(angle);
        this.vy = Math.sin(angle);
    }

    //释放火球
    shoot_fireball(tx,ty){
        let x = this.x , y = this.y;
        let radius =  0.01;
        let angle = Math.atan2(ty-y,tx-x);
        let vx=Math.cos(angle), vy = Math.sin(angle);
        let color = "orange";
        let speed = 0.5;
        let move_len = this.playground.height * 0.4; //是玩家半径的10倍
        let fireball = new FireBall(this.playground , this , x , y , radius , vx , vy ,color , speed , move_len , 0.01);
        this.fireballs.push(fireball);

        this.fireball_coldtime = 3;   // 火球技能CD3秒
        return fireball;
    }

    shoot_vertigo(tx,ty){
        let x = this.x , y = this.y;
        let radius =  0.005;
        let angle = Math.atan2(ty-y,tx-x);
        let vx=Math.cos(angle), vy = Math.sin(angle);
        let color = "blue";
        let speed = 0.25;
        let time = 0.75;
        let move_len = this.playground.height * 0.25; //是玩家半径的10倍
        let vertigo = new Vertigo(this.playground , this , x , y , radius , vx , vy ,time, 0 ,move_len, color , speed);

        this.fireballs.push(vertigo);
        this.vertigo_coldtime = 5;   // 火球技能CD3秒
        return vertigo;
    }



    blink(tx, ty){
        var x = this.x , y = this.y;
        let d = this.get_dist(x,y,tx,ty);
        d = Math.min(d , 0.6);
        let angle = Math.atan2(ty-y , tx-x);
        this.x += d * Math.cos(angle);
        this.y += d * Math.sin(angle);
        this.move_length = 0;
        this.blink_coldtime = 5;
    }

    destory_fireball(uuid) {
        for (var i = 0 ; i < this.fireballs.length ;i++){
            if(this.fireballs[i].uuid === uuid ){
                this.fireballs[i].distory();
                break;
            }
        }
    }

    // 受到攻击
    is_attacked(angle , damage, type, time){  // 1,击退 //2.眩晕
        for(var i = 0 ; i < 20 + Math.random()*5;i++){
            let x= this.x , y = this.y;
            let radius = this.radius *Math.random()*0.2;
            let angle = Math.PI * 2 * Math.random();
            let vx = Math.cos(angle),vy = Math.sin(angle);
            let color = this.color;
            let speed = this.speed* 20;
            let move_length = this.radius * Math.random()*20
            new Particle(this.playground, x, y ,radius ,vx ,vy ,color , speed,move_length);
        }
        this.radius -= damage;
        if (this.radius < this.eps){
            this.distory();
            if(this.character === "me") this.playground.end_game();
            return false;
        }
        if(type == 1){     // 击退
            this.damagex = Math.cos(angle);
            this.damagey = Math.sin(angle);
            this.damage_speed = damage * 200;
            this.speed = this.speed * 0.8;
        }else if (type === 2){
            this.state = "vertigo";
            this.vertigo_time = time;
            this.move_length = 0;
        }
    }

    // 收到攻击
    receive_attack(x, y , angle , damage , ball_uuid , attacker){
        attacker.destory_fireball(ball_uuid);
        this.x = x;
        this.y = y;
        this.is_attacked(angle , damage,1);
    }

    // 收到眩晕
    receive_vertigo(x , y , angle , time , damage , ball_uuid , attacker){
        attacker.destory_fireball(ball_uuid);
        this.x = x ;
        this.y = y ;
        this.is_attacked(angle, damage , 2 , time)
    }


    update(){

        if(this.character === "me" && this.playground.state === "fighting"){
            this.update_coldtime();
        }
        if(this.vertigo_time > this.eps){
            this.vertigo_time -= this.timedelta / 1000
        }else{
            this.state = "com"
        }
        this.update_move();
        this.update_win();
        this.render();
    }

    update_win(){
        if(this.playground.state === "fighting" && this.character === "me" && this.playground.players.length === 1){
            this.playground.scoreborad.win();
        }
    }

    update_coldtime(){

        this.fireball_coldtime -=this.timedelta / 1000;
        this.fireball_coldtime = Math.max(this.fireball_coldtime , 0);

        this.blink_coldtime -= this.timedelta / 1000;
        this.blink_coldtime = Math.max (this.blink_coldtime , 0 );

        this.vertigo_coldtime -=this.timedelta / 1000;
        this.vertigo_coldtime = Math.max (this.vertigo_coldtime , 0 );
        
    }

    update_move(){ // 更新玩家移动
        this.spent_time += this.timedelta / 1000
        if(this.spent_time > 4 && this.character === "robot" && Math.random() < 1 / 300.00 ){
            let s = Math.floor(Math.random()*10)
            let x , y;
            if(s>(this.playground.players.length-1)){
                x= this.playground.players[0].x +this.playground.players[0].vx * this.playground.players[0].speed * this.timedelta /1000 *0.3 ;
                y = this.playground.players[0].y+this.playground.players[0].vy * this.playground.players[0].speed * this.timedelta / 1000*0.3;
            }else{
                x=this.playground.players[s].x+ this.playground.players[s].vx * this.playground.players[s].speed * this.timedelta /1000 *0.3;
                y = this.playground.players[s].y+ this.playground.players[s].vy * this.playground.players[s].speed * this.timedelta /1000 *0.3;
            }
             this.shoot_vertigo(x,y);
        }

        if (this.damage_speed > this.eps){
            this.vx = 0;
            this.vy = 0;
            this.move_length = 0;
            this.x += this.damagex * this.damage_speed * this.timedelta / 1000;
            this.y += this.damagey * this.damage_speed * this.timedelta / 1000;
            this.damage_speed *= this.friction;
        }else{
            if(this.move_length < this.eps){
                this.move_length = 0;
                this.vx = this.vy = 0 ;
                if(this.character === "robot" && this.state === "com"){
                    let tx = Math.random() * this.playground.width / this.playground.scale;
                    let ty = Math.random() * this.playground.height / this.playground.scale;
                    this.move_to(tx,ty);
                }
            } else {
                if(this.state === "vertigo" && this.character === "me"){
                    this.move_length = 0;
                }
                let moved = Math.min( this.move_length  ,this.speed * this.timedelta / 1000); // 真实移动的距离
                this.x += this.vx * moved;
                this.y += this.vy * moved;
                this.move_length -= moved;
            }
        }
       
    }

    render(){  // 绘制玩家角色
        let scale = this.playground.scale;
        if(this.character !== "robot"){
            this.ctx.save();
            this.ctx.beginPath();
            this.ctx.arc(this.x * this.playground.scale,this.y* this.playground.scale,this.radius* this.playground.scale,0,Math.PI * 2,false);
            this.ctx.stroke();
            this.ctx.clip();
            this.ctx.drawImage(this.img,(this.x-this.radius) * scale,(this.y-this.radius) * scale,this.radius * 2 * scale,this.radius * 2 * scale);
            this.ctx.restore();
        }else{
            this.ctx.beginPath();
            this.ctx.arc(this.x * scale,this.y * scale,this.radius*scale,0,Math.PI*2,false);
            this.ctx.fillStyle=this.color;
            this.ctx.fill();
        }

        if(this.character === "me" && this.playground.state === "fighting"){
            this.render_skill_coldtime();
        }
    }
    
    vertigo_voice() {
        var audio = document.createElement("audio");
        audio.src = 'https://cloud-minapp-39228.cloud.ifanrusercontent.com/1nNF2DutwOoiWiSZ.mp3';
        audio.play();
    }

    render_skill_coldtime(){
        let scale = this.playground.scale;
        let x= 1.5, y = 0.9, r = 0.04;
        this.ctx.save();
        this.ctx.beginPath();
        this.ctx.arc(x * this.playground.scale,y* this.playground.scale,r* this.playground.scale,0,Math.PI * 2,false);
        this.ctx.stroke();
        this.ctx.clip();
        this.ctx.drawImage(this.fireball_img,(x-r) * scale,(y-r) * scale,r * 2 * scale,r * 2 * scale);
        this.ctx.restore();

        if(this.fireball_coldtime > this.eps && this.state === "com"){
            this.ctx.beginPath();
            this.ctx.moveTo(x * scale , y * scale);
            this.ctx.arc(x * scale,y * scale,r*scale,0 - Math.PI /2,Math.PI*2 * (1 - this.fireball_coldtime / 3) - Math.PI /2,true);
            this.ctx.lineTo(x * scale , y * scale);
            this.ctx.fillStyle= "rgba(0,0,255,0.6)";
            this.ctx.fill();
        }

        if(this.state != "com"){
            this.ctx.beginPath();
            this.ctx.arc(x * scale,y * scale,0, Math.PI * 2,true);
            this.ctx.fillStyle= "rgba(0,0,0,0)";
            this.ctx.fill();
        }

        x= 1.38, y = 0.9, r = 0.04;
        this.ctx.save();
        this.ctx.beginPath();
        this.ctx.arc(x * this.playground.scale,y* this.playground.scale,r* this.playground.scale,0,Math.PI * 2,false);
        this.ctx.stroke();
        this.ctx.clip();
        this.ctx.drawImage(this.vertigo_img,(x-r) * scale,(y-r) * scale,r * 2 * scale,r * 2 * scale);
        this.ctx.restore();

        if(this.vertigo_coldtime > this.eps && this.state === "com"){
            this.ctx.beginPath();
            this.ctx.moveTo(x * scale , y * scale);
            this.ctx.arc(x * scale,y * scale,r*scale,0 - Math.PI /2,Math.PI*2 * (1 - this.vertigo_coldtime / 5) - Math.PI /2,true);
            this.ctx.lineTo(x * scale , y * scale);
            this.ctx.fillStyle= "rgba(0,0,255,0.6)";
            this.ctx.fill();
        }

        if(this.state != "com"){
            this.ctx.beginPath();
            this.ctx.moveTo(x * scale , y * scale);
            this.ctx.arc(x * scale,y * scale,0, Math.PI * 2,true);
            this.ctx.lineTo(x * scale , y * scale);
            this.ctx.fillStyle= "rgba(0,0,255,0.6)";
            this.ctx.fill();
        }
        x= 1.62, y = 0.9, r = 0.04;
        this.ctx.save();
        this.ctx.beginPath();
        this.ctx.arc(x * this.playground.scale,y* this.playground.scale,r* this.playground.scale,0,Math.PI * 2,false);
        this.ctx.stroke();
        this.ctx.clip();
        this.ctx.drawImage(this.blink_img,(x-r) * scale,(y-r) * scale,r * 2 * scale,r * 2 * scale);
        this.ctx.restore();

        if(this.blink_coldtime > this.eps){
            this.ctx.beginPath();
            this.ctx.moveTo(x * scale , y * scale);
            this.ctx.arc(x * scale,y * scale,r*scale,0 - Math.PI /2,Math.PI*2 * (1 - this.blink_coldtime / 5) - Math.PI /2,true);
            this.ctx.lineTo(x * scale , y * scale);
            this.ctx.fillStyle= "rgba(0,0,255,0.6)";
            this.ctx.fill();
        }

        if(this.state != "com"){
            this.ctx.beginPath();
            this.ctx.moveTo(x * scale , y * scale);
            this.ctx.arc(x * scale,y * scale,0, Math.PI * 2,true);
            this.ctx.lineTo(x * scale , y * scale);
            this.ctx.fillStyle= "rgba(0,0,255,0.6)";
            this.ctx.fill();
        }
    }
    on_distory(){
        for(var i = 0 ; i < this.playground.players.length ; i++){
            if(this === this.playground.players[i]){
                this.playground.players.splice(i,1);
                break;
            }
        }

    }
}
